import router from '@/router'
import { apiRouteList } from '@/api/system/menu'
import { staticRoutes } from './staticRoutes'
import { useMenuStore } from '@/stores/menu'

// 获取views文件夹下所有vue文件的模块映射
const modules = import.meta.glob('@/views/**/*.vue')

/**
 * 路由处理器 - 支持深度合并
 * @description 合并处理动态和静态路由，处理组件引入和排序；路由冲突时动态路由优先级大于静态路由
 */
export async function routerHandler() {
  // 执行合并和处理流程
  let dynamicRoutes = []

  try {
    // 获取接口中动态路由菜单
    const res = await apiRouteList()
    dynamicRoutes = res.data || []

    // 合并动态/静态路由
    const mergeRoutes = buildRouteFlat(staticRoutes, dynamicRoutes)

    // 注册路由
    registerRoutes(mergeRoutes)

    // 缓存所有路由
    useMenuStore().allRoutesFlat = mergeRoutes
  } catch (error) {
    return Promise.reject(error)
  }
}

/**
 * 注册路由
 * @param {Array} routes 路由列表
 */
function registerRoutes(routes) {
  // 处理布局及component文件动态引入
  routes.forEach((item) => {
    // views文件路径动态导入
    if (item.component && typeof item.component == 'string') {
      item.component = modules['/src/views' + item.component + '.vue']
    }
    // 使用布局
    if (item.meta.layouts) {
      router.addRoute('layouts', item)
    }
    // 纯净无布局页面
    else {
      router.addRoute(item)
    }
  })
}

/**
 * 重置路由
 * @description 重置所有路由
 */
export function resetRouters() {
  const routes = useMenuStore().allRoutesFlat || []
  routes.forEach((item) => {
    if (item.name && router.hasRoute(item.name)) {
      router.removeRoute(item.name)
    }
  })
}

/**
 * 扁平路由列表
 * @description 用于构建过滤处理路由
 * @param {Array} flatStatic - 静态扁平路由数组
 * @param {Array} flatDynamic - 接口动态扁平路由，冲突时优先级大于静态路由
 * @returns
 */
export function buildRouteFlat(flatStatic, flatDynamic) {
  const filtertStatic = flatStatic.filter((item) => {
    // TODO 后续还需追加对authCode的权限判断
    return !item.meta?.disabled
  })

  // 以flatDynamic为主，过滤flatStatic中冲突的name路由，并warn提示
  // 1. 创建动态路由名称的快速查找集合（Set）
  const dynamicRouteNames = new Set(flatDynamic.map((route) => route.name))

  // 2. 用于收集冲突路由信息，便于后续警告
  const conflictRoutes = []

  // 3. 过滤静态路由，排除在动态路由中已存在的项
  const finalStaticRoutes = filtertStatic.filter((staticRoute) => {
    const isConflict = dynamicRouteNames.has(staticRoute.name)
    if (isConflict) {
      conflictRoutes.push(staticRoute.name) // 记录冲突的路由名
    }
    return !isConflict // 返回 false 表示过滤掉该项
  })

  // 4. 输出冲突警告
  if (conflictRoutes.length > 0) {
    console.warn(`检测到 ${conflictRoutes.length} 个路由冲突，动态路由已覆盖以下静态路由：${conflictRoutes.join(', ')}`)
  }

  // 5. 合并路由（动态路由优先，无冲突的静态路由在后）
  const mergedRoutes = [...flatDynamic, ...finalStaticRoutes]

  return mergedRoutes
}

/**
 * 菜单树构建
 * @param {Array} flatMenuList - 扁平菜单数组
 * @param {Object} options - 配置选项
 * @property {boolean} options.ignoreOrphanNode - 是否忽略孤儿节点：true舍去(默认) | false作为根节点
 * @property {string} options.rootParentName - 根节点的父节点标识，默认空字符串
 * @property {string} options.idKey - 节点ID字段名，默认name
 * @property {string} options.parentIdKey - 父节点ID字段名，默认parentName
 * @property {string} options.childrenKey - 子节点字段名，默认children
 * @property {string} options.sortKey - 排序字段路径，默认meta.sort
 * @property {boolean} options.enableSorting - 是否启用排序，默认true
 * @returns {Array} 树状菜单结构
 */
export function buildMenuTree(flatMenuList, options = {}) {
  const {
    ignoreOrphanNode = true,
    rootParentName = '',
    idKey = 'name',
    parentIdKey = 'parentName',
    childrenKey = 'children',
    sortKey = 'meta.sort',
    enableSorting = true,
  } = options

  // 循环引用检测
  const visited = new Set()

  // 构建节点映射
  const nodeMap = new Map()
  const missingParents = new Set()

  flatMenuList.forEach((item) => {
    const nodeId = item[idKey]
    if (visited.has(nodeId)) {
      console.warn(`检测到重复的节点ID: ${nodeId}`)
      return
    }
    visited.add(nodeId)

    nodeMap.set(nodeId, {
      ...item,
      [childrenKey]: [],
    })
  })

  // 构建树结构
  const tree = []

  flatMenuList.forEach((item) => {
    const nodeId = item[idKey]
    const parentId = item[parentIdKey]
    const currentNode = nodeMap.get(nodeId)

    if (!parentId || parentId === rootParentName) {
      tree.push(currentNode)
    } else {
      const parentNode = nodeMap.get(parentId)
      if (parentNode) {
        parentNode[childrenKey].push(currentNode)
      } else {
        if (ignoreOrphanNode) {
          console.warn(`孤儿节点 ${nodeId} 已被舍去：其父节点 ${parentId} 不存在`)
        } else {
          missingParents.add(parentId)
          // 将孤儿节点作为根节点处理
          tree.push(currentNode)
        }
      }
    }
  })

  // 输出警告信息
  if (missingParents.size > 0) {
    console.warn(`未找到以下父节点: ${Array.from(missingParents).join(', ')}`)
  }

  // 辅助函数：获取嵌套对象值
  const getNestedValue = (obj, path) => {
    return path.split('.').reduce((current, key) => {
      return current && current[key] !== undefined ? current[key] : undefined
    }, obj)
  }

  // 递归排序函数
  const sortTree = (nodes) => {
    if (!enableSorting || !nodes.length) return nodes

    return nodes
      .map((node) => {
        return {
          ...node,
          [childrenKey]: sortTree(node[childrenKey]),
        }
      })
      .sort((a, b) => {
        const sortA = getNestedValue(a, sortKey)
        const sortB = getNestedValue(b, sortKey)
        return (sortA || 0) - (sortB || 0)
      })
  }

  return sortTree(tree)
}
